package cn.yunhe.advice;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

/**
 * @author Juni
 * @date 2021/1/20
 */
@Component
//标注该类是一个切面类
@Aspect
//强制使用cglib代理
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class ItemAdvice2 {

    @Pointcut("execution(* cn.yunhe.dao.impl..*(..))")
    public void pointCut(){}

    /**
     * 执行目标对象功能之前要做的事情
     */
    @Before("pointCut()")
    public void before(){
        System.out.println("去哪能买到，还不用出门，买到的真不真");
    }

    /**
     * 执行目标对象功能之后要做的事情
     */
    @After("pointCut()")
    public void after(){
        System.out.println("验证真假，消毒等等");
    }

    /**
     * 出现异常后要做的事情
     */
    @AfterThrowing("pointCut()")
    public void exception(){
        System.out.println("功能异常日志");
    }

    /**
     * 返回结果后要做的事情
     */
    @AfterReturning("pointCut()")
    public void returnMethod(){
        System.out.println("方法返回结果之后要做的事情");
    }

    /**
     * 环绕通知
     * @param proceedingJoinPoint 包含了目标对象的相关信息
     *  该通知的返回值类型要和目标方法的返回值类型保持一致
     */
    public Object around(ProceedingJoinPoint proceedingJoinPoint){
        try {
            System.out.println("环绕通知：目标方法执行之前要做的事情");
            proceedingJoinPoint.proceed();
            System.out.println("环绕通知：目标方法执行之后要做的事情");
        } catch (Throwable throwable) {
            System.out.println("环绕通知：出现异常后要做的事情");
            throwable.printStackTrace();
        } finally {
            System.out.println("环绕通知：目标方法返回结构之后要做的事情");
        }
        return 0;
    }
}
